package jp.co.menox.tmserver.channel;

import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import jp.co.menox.tmcommon.common.DataConst;
import jp.co.menox.tmcommon.meta.LendingMeta;
import jp.co.menox.tmcommon.model.Lending;
import jp.co.menox.tmcommon.model.LendingHistory;
import jp.co.menox.tmserver.service.LendingHistoryService;

import org.slim3.memcache.Memcache;

import com.google.appengine.api.channel.ChannelMessage;
import com.google.appengine.api.channel.ChannelService;
import com.google.appengine.api.channel.ChannelServiceFactory;

/**
 * サーバチーム用Push通信用
 * @author
 *
 */
public class MessageSender {

    /**
     * 現在接続中のユーザに対して、関連する貸し借りリストを送信する。<br />
     * 【貸す人】        
     * 0：未承認
     * ⇒承認待ちリスト
     * 1：承認済
     * ⇒貸し出し待ちリスト
     * 2：貸出中
     * ⇒貸出中件数のみ
     * 【借りる人】
     * 0：未承認
     * ⇒申し込み中リスト
     * 1：承認済
     * ⇒借り出し待ちリスト
     * 2：貸出中
     * ⇒借り出し中リスト
     * 5：申請却下
     * ⇒申込却下リスト（表示期間制限）
     * @param lastChangedModel 最終変更モデル
     */
    public static void sendCurrentModelList(LendingHistory lastChangedModel) {

        // 最終変更モデル（lendingHistoryId）
        Map<Long, Long> lastUpdateList 
            = Memcache.<Map<Long, Long>>get(DataConst.SERVERKEY_CHANNEL_LASTSTATUSCHANGEDMODEL);
        if (lastUpdateList == null) {
            lastUpdateList = Collections.synchronizedMap(new HashMap<Long, Long>());
        }
        
        long lendingUser = lastChangedModel.getLendingUser();
        long borrowingUser = lastChangedModel.getBorrowingUser();
        lastUpdateList.put(lendingUser, lastChangedModel.getId());
        lastUpdateList.put(borrowingUser, lastChangedModel.getId());

        sendCurrentModelList(lendingUser);
        sendCurrentModelList(borrowingUser);
    }

    /**
     * 現在接続中のユーザに対して、関連する貸し借りリストを送信する。<br />
     */
    public static void sendCurrentModelList() {

        // 現在接続中リスト
        Map<Long, Date> activeList 
            = Memcache.<Map<Long, Date>>get(DataConst.SERVERKEY_CHANNEL_LIST);
        if (activeList == null) {
            return;
        }

        for (Entry<Long, Date> entry : activeList.entrySet()) {
            
            // 送信対象者
            long userId = entry.getKey();
            sendCurrentModelList(userId);

        }

    }

    /**
     * 指定したユーザに対して、関連する貸し借りリストを送信する。<br />
     * 接続状況はチェックしないので、接続していない場合には無言で送信失敗する。
     * @param userId
     */
    public static void sendCurrentModelList(long userId) {
        LendingHistoryService service = new LendingHistoryService();
        ChannelService channelService = ChannelServiceFactory.getChannelService();

        // 最終変更モデル（lendingHistoryId）
        Map<Long, Long> lastUpdateList 
            = Memcache.<Map<Long, Long>>get(DataConst.SERVERKEY_CHANNEL_LASTSTATUSCHANGEDMODEL);
        long lastUpdatedLendingHistoryId = Long.MIN_VALUE;
        long lastUpdatedForLendingId = Long.MIN_VALUE;
        if (lastUpdateList != null && lastUpdateList.containsKey(userId)) {
            lastUpdatedLendingHistoryId = lastUpdateList.get(userId);
            lastUpdatedForLendingId = service.select(lastUpdatedLendingHistoryId).getLendingId();
        }

        // 貸している送信用
        List<Lending> lendingMisyouninModelList 
            = service.getLendingListByLendingUser(userId, DataConst.STATUS_MISYOUNIN);
        List<Lending> lendingSyouninzumiModelList 
            = service.getLendingListByLendingUser(userId, DataConst.STATUS_SYOUNINZUMI);
        List<Lending> lendingKashidasityuModelList 
            = service.getLendingListByLendingUser(userId, DataConst.STATUS_KASHIDASHITYU);

        // 借りている送信用
        List<Lending> borrowingMisyouninModelList 
            = service.getLendingListByBorrowingUser(userId, DataConst.STATUS_MISYOUNIN);
        List<Lending> borrowingSyouninzumiModelList 
            = service.getLendingListByBorrowingUser(userId, DataConst.STATUS_SYOUNINZUMI);
        List<Lending> borrowingKashidasityuModelList 
            = service.getLendingListByBorrowingUser(userId, DataConst.STATUS_KASHIDASHITYU);
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -10);
        List<Lending> borrowingShinseikyakkaModelList 
            = service.getRejectedLendingListByBorrowingUser(userId, cal.getTime());
        // JSONデータ作成
        LendingMeta m = LendingMeta.get();

        String lendingMisyouninList = m.modelsToJson(lendingMisyouninModelList.toArray());
        String lendingSyouninzumiList = m.modelsToJson(lendingSyouninzumiModelList.toArray());
//        String lendingKashidasityuList = m.modelsToJson(lendingKashidasityuModelList.toArray());

        String borrowingMisyouninList = m.modelsToJson(borrowingMisyouninModelList.toArray());
        String borrowingSyouninzumiList = m.modelsToJson(borrowingSyouninzumiModelList.toArray());
        String borrowingKashidasityuList = m.modelsToJson(borrowingKashidasityuModelList.toArray());
        String borrowingShinseikyakkaList = m.modelsToJson(borrowingShinseikyakkaModelList.toArray());

        StringBuffer message = new StringBuffer();
        message.append("{");

        message.append("\"lastUpdatedLendingHistoryId\": ");
        message.append(lastUpdatedLendingHistoryId);
        message.append(", ");
        message.append("\"lastUpdatedForLendingId\": ");
        message.append(lastUpdatedForLendingId);
        message.append(", ");

        message.append("\"lendingMisyounin\": ");
        message.append(lendingMisyouninList);
        message.append(", ");
        message.append("\"lendingSyouninzumi\": ");
        message.append(lendingSyouninzumiList);
        message.append(", ");
        message.append("\"lendingKashidasityuCount\": ");
        message.append(lendingKashidasityuModelList.size());

        message.append(", ");
        message.append("\"borrowingMisyounin\": ");
        message.append(borrowingMisyouninList);
        message.append(", ");
        message.append("\"borrowingSyouninzumi\": ");
        message.append(borrowingSyouninzumiList);
        message.append(", ");
        message.append("\"borrowingKashidasityu\": ");
        message.append(borrowingKashidasityuList);
        message.append(", ");
        message.append("\"borrowingShinseikyakka\": ");
        message.append(borrowingShinseikyakkaList);

        message.append("}");
        
        // 送信
        channelService.sendMessage(
            new ChannelMessage(Long.toString(userId), message.toString()));

    }

}
